import os

import cv2
import requests
import io
from io import BytesIO

import numpy as np
import requests
from PIL import Image

class DragVerifyImageUtil:
    """处理拖动验证码图像相关操作的工具类。"""

    def __init__(self):
        # 初始化验证码图片文件名
        self.verify_background_name = "verify_background.jpeg"
        self.verify_slider_name = "verify_slider.png"

    def get_images(self, background_img_url, slider_img_url, background_size=None, slider_size=None):
        # 下载背景图片
        background_img_content = requests.get(background_img_url).content
        background_img = Image.open(BytesIO(background_img_content))
        # 调整背景图片尺寸
        if background_size:
            background_img = background_img.resize(background_size)
        background_img.save(self.verify_background_name)

        # 下载滑块图片
        slider_img_content = requests.get(slider_img_url).content
        slider_img = Image.open(BytesIO(slider_img_content))
        # 调整滑块图片尺寸
        if slider_size:
            slider_img = slider_img.resize(slider_size)
        slider_img.save(self.verify_slider_name)

    def preprocess_image(self):
        # 读取并灰度化图片
        verify_background_img = cv2.imread(self.verify_background_name, cv2.IMREAD_GRAYSCALE)
        verify_slider_img = cv2.imread(self.verify_slider_name, cv2.IMREAD_GRAYSCALE)
        # 应用高斯模糊来减少噪声
        verify_background_img = cv2.GaussianBlur(verify_background_img, (5, 5), 0)
        verify_slider_img = cv2.GaussianBlur(verify_slider_img, (5, 5), 0)
        # 使用Canny边缘检测
        verify_background_img = cv2.Canny(verify_background_img, 50, 150)
        verify_slider_img = cv2.Canny(verify_slider_img, 50, 150)
        return verify_background_img, verify_slider_img

    def find_slider_position(self, verify_background_img, verify_slider_img):
        # 在不同尺度下进行模板匹配
        best_match_val = -1
        best_match_loc = None
        for scale in np.linspace(0.5, 1.5, 20):
            resized_slider = cv2.resize(verify_slider_img, None, fx=scale, fy=scale, interpolation=cv2.INTER_AREA)
            if resized_slider.shape[0] > verify_background_img.shape[0] or resized_slider.shape[1] > verify_background_img.shape[1]:
                continue
            result = cv2.matchTemplate(verify_background_img, resized_slider, cv2.TM_CCOEFF_NORMED)
            _, max_val, _, max_loc = cv2.minMaxLoc(result)
            if max_val > best_match_val:
                best_match_val = max_val
                best_match_loc = max_loc

        # 验证匹配结果
        # if best_match_val < 0.8:  # 设定一个合理的阈值
        #     raise ValueError("匹配不够准确，可能需要调整图像或参数。")

        # 返回最佳匹配位置
        os.remove(self.verify_background_name)
        os.remove(self.verify_slider_name)
        return best_match_loc[0]


if __name__ == "__main__":
    # 示例用法
    background_img_url = "https://p6-catpcha.byteimg.com/tos-cn-i-188rlo5p4y/0e3ed7d707ef42638ca7930e095431a3~tplv-188rlo5p4y-2.jpeg"
    slider_img_url = "https://p6-catpcha.byteimg.com/tos-cn-i-188rlo5p4y/09991905cab34b5ea217dd44d4c1f6d1~tplv-188rlo5p4y-1.png"
    util = DragVerifyImageUtil()
    util.get_images(background_img_url, slider_img_url)
    verify_background_img, verify_slider_img = util.preprocess_image()
    util.find_slider_position(verify_background_img, verify_slider_img)
